extends Node2D

var next_spawn_interfered : bool = false

class ObstacleDesc:
	var name : String
	var value : int
	var resource : Texture2D

	func _init(_name: String, _value: int, _resource: Texture2D) -> void:
		name = _name
		value = _value
		resource = _resource

var ObstacleMap = {
	"Dark" : ObstacleDesc.new("Dark", 0, Preload.Dark_Obstacle),
	"Light" : ObstacleDesc.new("Light", 1, Preload.Light_Obstacle),
	"Refraction" : ObstacleDesc.new("Refraction", 5, Preload.Refraction_Obstacle),
	"Interfered" : ObstacleDesc.new("Interfered", 10, Preload.Interfered_Obstacle),
	"Seam" : ObstacleDesc.new("Seam", -2, Preload.SeamUncharged_Obstacle)
}

func _random_pick_obstacle() -> ObstacleDesc:
	var tmp = randf()

	if Global.G_phase == Global.Phase.Day:
		if tmp < 0.05: # 5%
			return ObstacleMap.Refraction
		if tmp < 0.5: # 45%
			return ObstacleMap.Dark
		else: # 50%
			return ObstacleMap.Light

	if tmp < 0.1: # 10%
		return ObstacleMap.Seam
	# 90%
	return ObstacleMap.Light

func _create_obstacle(desc: ObstacleDesc, pos: Vector2) -> CharacterBody2D:
	var obstacle = Preload.ObstacleScene.instantiate()

	var shape = RectangleShape2D.new()
	shape.size = desc.resource.get_size()
	
	obstacle.init(desc.resource, pos, shape, desc.value)
	add_child(obstacle)
	
	return obstacle

func _create_upper(posX: float, desc: ObstacleDesc, offset: float = 0) -> void:
	var y_upper = desc.resource.get_size().y / 2 - _random_offset_y(desc) + offset
	var obstacle_upper = _create_obstacle(desc, Vector2(posX, y_upper))
	obstacle_upper.get_node("Sprite2D").flip_v = true

func _create_lower(posX: float, desc: ObstacleDesc, offset: float = 0) -> void:
	var y_lower = Global.W_resolution.y - desc.resource.get_size().y / 2 + _random_offset_y(desc) + offset
	_create_obstacle(desc, Vector2(posX, y_lower))

func _create_middle(posX: float, desc: ObstacleDesc, offset: float = 0) -> void:
	var y_middle = Global.W_resolution.y / 2 + offset
	_create_obstacle(desc, Vector2(posX, y_middle))

func _random_offset_y(desc: ObstacleDesc) -> float: 
	if (desc == ObstacleMap.Light) or (desc == ObstacleMap.Dark):
		return randi_range(120, 220) # BIGGER MEANS BIGGER INTERVAL OF OBSTACLES
	return 0

func spawn_obstacle(
	posX: float = Global.W_resolution.x
) -> void:
	# Logic of spawning obstacles
	var temp_random_offset_y = randi_range(-105, 105)
	if next_spawn_interfered:
		_create_upper(posX, ObstacleMap.Interfered)
		_create_lower(posX, ObstacleMap.Interfered)
		next_spawn_interfered = false
		return

	if Global.G_phase == Global.Phase.Day:
		_create_upper(posX, _random_pick_obstacle(), temp_random_offset_y)
		_create_lower(posX, _random_pick_obstacle(), temp_random_offset_y)
		return
	
	if _random_pick_obstacle() == ObstacleMap.Seam:
		_create_middle(posX, ObstacleMap.Seam, temp_random_offset_y)
		return

	_create_upper(posX, ObstacleMap.Light, temp_random_offset_y)
	_create_lower(posX, ObstacleMap.Light, temp_random_offset_y)
